package io.shuttle.mbe.core

import android.os.Handler
import android.os.HandlerThread
import androidx.annotation.VisibleForTesting
import java.util.concurrent.CountDownLatch
import java.util.concurrent.ExecutionException
import java.util.concurrent.Future
import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeoutException
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.concurrent.Volatile


/**
 * 基于 HandlerThread 实现的类似 JavaScript Promise 的类
 * 同时实现 Java Future 接口，提供完整的异步编程支持
 */
class Promise<T> : Future<T> {
    // Promise 状态枚举
    private enum class State {
        PENDING,  // 等待中
        FULFILLED,  // 已完成
        REJECTED,  // 已拒绝
        CANCELLED // 已取消
    }

    // 实例变量
    @Volatile
    private var mState = State.PENDING
    private var mResult: T? = null
    private var mError: Throwable? = null
    private val mLatch = CountDownLatch(1)
    private val mCancelled = AtomicBoolean(false)
    private val mCallbacks: MutableList<PromiseCallback<T?>> = ArrayList<PromiseCallback<T?>>()

    // 构造函数
    constructor(executor: PromiseExecutor<T?>) {
        try {
            executor.run {
                execute(
                    { value: T? -> resolve(value) },
                    { error: Throwable? -> reject(error) }
                )
            }
        } catch (e: Exception) {
            reject(e)
        }
    }

    // 私有构造函数，用于内部创建已完成的 Promise
    private constructor(result: T?, error: Throwable?, state: State?) {
        if (state == State.FULFILLED) {
            mResult = result
            mState = State.FULFILLED
        } else if (state == State.REJECTED) {
            mError = error
            mState = State.REJECTED
        }
        mLatch.countDown()
    }

    // ========== Future 接口实现 ==========
    override fun cancel(mayInterruptIfRunning: Boolean): Boolean {
        if (mState != State.PENDING) {
            return false
        }

        if (mCancelled.compareAndSet(false, true)) {
            mState = State.CANCELLED
            mLatch.countDown()
            executeCallbacks()
            return true
        }
        return false
    }

    override fun isCancelled(): Boolean {
        return mState == State.CANCELLED
    }

    override fun isDone(): Boolean {
        return mState != State.PENDING
    }

    @Throws(InterruptedException::class, ExecutionException::class)
    override fun get(): T? {
        mLatch.await()
        return this.result
    }

    @Throws(InterruptedException::class, ExecutionException::class, TimeoutException::class)
    override fun get(timeout: Long, unit: TimeUnit): T? {
        if (!mLatch.await(timeout, unit)) {
            throw TimeoutException("Promise timed out after $timeout $unit")
        }
        return this.result
    }

    // ========== Promise 特有方法 ==========
    /**
     * 添加成功回调
     */
    fun <U> then(onFulfilled: Function<T?, U?>?): Promise<U?> {
        return then<U?>(onFulfilled, null)
    }

    /**
     * 添加成功和失败回调
     */
    fun <U> then(
        onFulfilled: Function<T?, U?>?,
        onRejected: Function<Throwable?, U?>?
    ): Promise<U?> {
        val nextPromise = Promise<U?>(PromiseExecutor { resolve, reject -> })

        val callback: PromiseCallback<T?> = object : PromiseCallback<T?> {
            override fun onFulfilled(result: T?) {
                try {
                    if (onFulfilled != null) {
                        val newResult = onFulfilled.apply(result)
                        nextPromise.resolve(newResult)
                    } else {
                        // 如果没有处理函数，直接传递结果
                        nextPromise.resolve(result as U?)
                    }
                } catch (e: Exception) {
                    nextPromise.reject(e)
                }
            }

            override fun onRejected(error: Throwable?) {
                try {
                    if (onRejected != null) {
                        val result = onRejected.apply(error)
                        nextPromise.resolve(result)
                    } else {
                        nextPromise.reject(error)
                    }
                } catch (e: Exception) {
                    nextPromise.reject(e)
                }
            }

            override fun onCancelled() {
                nextPromise.cancel(false)
            }
        }

        addCallback(callback)
        return nextPromise
    }

    /**
     * 添加错误处理回调
     */
    fun catchError(onRejected: Function<Throwable?, T?>?): Promise<T?> {
        return then<T?>(null, onRejected)
    }

    // ========== 私有方法 ==========
    private fun resolve(result: T?) {
        if (mState == State.PENDING && !mCancelled.get()) {
            mResult = result
            mState = State.FULFILLED
            mLatch.countDown()
            executeCallbacks()
        }
    }

    private fun reject(error: Throwable?) {
        if (mState == State.PENDING && !mCancelled.get()) {
            mError = error
            mState = State.REJECTED
            mLatch.countDown()
            executeCallbacks()
        }
    }

    @get:Throws(ExecutionException::class)
    private val result: T?
        get() {
            when (mState) {
                State.FULFILLED -> return mResult
                State.REJECTED -> throw ExecutionException(mError)
                State.CANCELLED -> throw ExecutionException(InterruptedException("Promise was cancelled"))
                else -> throw IllegalStateException("Promise is still pending")
            }
        }

    private fun addCallback(callback: PromiseCallback<T?>) {
        synchronized(mCallbacks) {
            if (mState == State.PENDING) {
                mCallbacks.add(callback)
            } else {
                // 如果已经完成，立即执行回调
                runOnPromiseThread { executeCallback(callback) }
            }
        }
    }

    private fun executeCallbacks() {
        Companion.runOnPromiseThread {
            synchronized(mCallbacks) {
                for (callback in mCallbacks) {
                    executeCallback(callback)
                }
                mCallbacks.clear()
            }
        }
    }

    private fun executeCallback(callback: PromiseCallback<T?>) {
        when (mState) {
            State.FULFILLED -> callback.onFulfilled(mResult)
            State.REJECTED -> callback.onRejected(mError)
            State.CANCELLED -> callback.onCancelled()
            // FIXME:
            State.PENDING -> Unit
        }
    }

    // ========== 内部接口 ==========
    /**
     * Promise 执行器接口
     */
    fun interface PromiseExecutor<T> {
        @Throws(Exception::class)
        fun execute(resolve: Resolver<T?>?, reject: Rejector?)
    }

    /**
     * 成功回调接口
     */
    fun interface Resolver<T> {
        fun resolve(value: T?)
    }

    /**
     * 失败回调接口
     */
    fun interface Rejector {
        fun reject(error: Throwable?)
    }

    /**
     * 函数式接口
     */
    fun interface Function<T, R> {
        @Throws(Exception::class)
        fun apply(input: T?): R?
    }

    /**
     * 内部回调接口
     */
    private interface PromiseCallback<T> {
        fun onFulfilled(result: T?)
        fun onRejected(error: Throwable?)
        fun onCancelled()
    }

    companion object {
        @Volatile
        private var handler: Handler? = null

        @VisibleForTesting
        internal fun setHandlerForTesting(h: Handler) {
            handler = h
        }

        private fun getHandler(): Handler {
            return handler ?: synchronized(this) {
                handler ?: Handler(HandlerThread("promise").apply { start() }.looper).also {
                    handler = it
                }
            }
        }

        fun runOnPromiseThread(block: () -> Unit) {
            getHandler().post(block)
        }

        // ========== 静态工厂方法 ==========
        /**
         * 创建一个已完成的 Promise
         */
        fun <T> resolve(value: T?): Promise<T> {
            return Promise<T>(value, null, State.FULFILLED)
        }

        /**
         * 创建一个已拒绝的 Promise
         */
        fun <T> reject(error: Throwable?): Promise<T> {
            return Promise<T>(null, error, State.REJECTED)
        }

        /**
         * 等待所有 Promise 完成
         */
        fun <T> all(promises: MutableList<Promise<T?>>): Promise<MutableList<T?>> {
            return Promise<MutableList<T?>>(PromiseExecutor { resolve, reject ->
                if (promises.isEmpty()) {
                    resolve!!.resolve(null)
                    return@PromiseExecutor
                }
                runOnPromiseThread {
                    val results: MutableList<T?> = ArrayList<T?>()
                    val hasError = AtomicBoolean(false)
                    val allLatch = CountDownLatch(promises.size)

                    for (i in promises.indices) {
                        val index = i
                        results.add(null) // 预分配空间

                        val promise = promises.get(index)
                        promise.then<T?>(
                            { result: T? ->
                                synchronized(results) {
                                    results.set(index, result)
                                }
                                allLatch.countDown()
                                result
                            },
                            { error: Throwable? ->
                                if (hasError.compareAndSet(false, true)) {
                                    reject!!.reject(error)
                                }
                                null
                            }
                        )
                    }


                    // 等待所有完成
                    Thread(Runnable {
                        try {
                            allLatch.await()
                            if (!hasError.get()) {
                                resolve!!.resolve(results)
                            }
                        } catch (e: InterruptedException) {
                            reject!!.reject(e)
                        }
                    }).start()
                }
            })
        }
    }
}